package com.jetsen.jbmp.patch.dialog;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class ParamDialog extends Dialog {
	private Text txtDpatchzip;
	private Tree tree;
	
	private IJavaProject javaProject;
	
	private String projectName;
	
	private String subFloder = "bin";

	/**
	 * Create the dialog.
	 * @param parentShell
	 */
	public ParamDialog(Shell parentShell,IJavaProject javaProject) {
		super(parentShell);
		this.javaProject = javaProject;
		this.projectName = javaProject.getProject().getName();
	}

	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		GridLayout gridLayout = (GridLayout) container.getLayout();
		gridLayout.numColumns = 2;
		
		Label label = new Label(container, SWT.NONE);
		label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		label.setText("\u5BFC\u51FA\u8DEF\u5F84");
		
		txtDpatchzip = new Text(container, SWT.BORDER);
		txtDpatchzip.setText("D:/patch.zip");
		txtDpatchzip.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label label_1 = new Label(container, SWT.NONE);
		label_1.setText("\u9009\u62E9\u6587\u4EF6");
		
		tree = new Tree(container, SWT.BORDER | SWT.CHECK);
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		fillTree(tree, javaProject.getProject().getLocation().toFile());
		
		return container;
	}
	
	private void fillTree(Tree tree, File file){
		TreeItem root = new TreeItem(tree, SWT.NULL);
		root.setText(file.getName());
		root.setData(file);
		if(file.isDirectory()){
			for(File f : file.listFiles(new FileFilter() {
				@Override
				public boolean accept(File arg0) {
					if(subFloder.equals(arg0.getName())){
						return true;
					}
					return false;
				}
			})){
				if(!f.getName().toString().startsWith(".")){
					fileTree(root, f);
				}
			}
		}
	}
	
	private void fileTree(TreeItem parent, File file){
		TreeItem item = new TreeItem(parent, SWT.NULL);
		item.setText(file.getName());
		item.setData(file);
		if(file.isDirectory()){
			for(File f : file.listFiles()){
				if(!f.getName().toString().startsWith(".")){
					fileTree(item, f);
				}
			}
		}
	}

	/**
	 * Create contents of the button bar.
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(451, 505);
	}

	@Override
	protected void buttonPressed(int buttonId) {
		if (buttonId == IDialogConstants.OK_ID) {  
			patch();
		}
		super.buttonPressed(buttonId);
	}
	
	private void patch(){
		String zipPath = txtDpatchzip.getText();
		
		ZipOutputStream out = null;
		try {
			out = new ZipOutputStream(new CheckedOutputStream(new FileOutputStream(zipPath), new Adler32()));
			
			for(TreeItem item : tree.getItems()){
				patch(item, out);
			}
			
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void patch(TreeItem item, ZipOutputStream out){
		if(item.getChecked()){
			File file = (File) item.getData();
			if(!file.isDirectory()){
				try {
					BufferedOutputStream bos = new BufferedOutputStream(out);
					BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
					String path = file.getAbsolutePath();
					out.putNextEntry(new ZipEntry(projectName + path.substring(path.indexOf(subFloder) + subFloder.length())));
					
					int len = -1;
					byte[] buff = new byte[1024];
					while((len = bis.read(buff)) != -1){
						bos.write(buff, 0, len);
					}
					bis.close();
					bos.flush();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		for(TreeItem ti : item.getItems()){
			patch(ti, out);
		}
	}
}
